# Convert `Makefile.in' into a Makefile for MSDOS.
# Copyright (C) 1991 Free Software Foundation, Inc.
# Francois Pinard <pinard@iro.umontreal.ca>, 1991

# Standard Input contains a substitution list quite similar to what is
# found in `config.status', but adapted for MSDOS.  These are studied
# and used for turning `Makefile.in' into a usable Makefile for MSDOS
# on Standard Output.  It is assumed that the MSDOS port of GNU make
# is used on the MSDOS side.

# Remember all the substitutions indicated by Standard Input.

while (<>)
{
    next if /^$/;
    next if /^#/;
    if (/^PROGS="(.*)"/ || /^PROGS=(.*)/)
    {
	foreach $prog (split (' ', $1))
	{
	    $cache{$prog} = &filename ("$prog.exe");
	}
    }
    elsif (/^(\w+)="(.*)"$/)
    {
	($var, $value) = ($1, $2);
	$value =~ s/\\"/"/g;
	$config{$var} = $value;
    }
    elsif (/^(\w+)=(.*)/)
    {
	$config{$1} = $2;
    }
    else
    {
	print STDERR "*** Error on line $.: $_";
	next;
    }
}


# Beware the clash between TAGS and tags.

$cache{"TAGS"} = "tagse";


# Transform `Makefile.in' into `makefile.dos'.

open (INPUT, "Makefile.in") || die "Cannot read Makefile.in\n";
print "# Generated automatically by `configdos.pl'.\n";
while (<INPUT>)
{
    # Execute @...@ substitutions.

    while (/(.*)@(\w+)@(.*)/)
    {
	$_ = $1 . $config{$2} . $3 . "\n";
    }

    # Get rid of comments right now.

    if (/^\#/)
    {
	print;
	next;
    }

    # Some macros annonce list of files.  Study them.

    if (/^(DISTFILES|\w*SOURCES|\w*SRCS|\w*OBJECTS|\w*OBJS)\s*=\s*(.*)/)
    {
	&studylist ($2);
	$studylist = 1;
    }
    elsif ($studylist)
    {
	&studylist ($_);
    }

    if ($studylist && ! /\\$/)
    {
	$studylist = "";
    }

    # Extract each word of the line and process it.

    ($_, $line) = /^(\w+\s*=\s*)?(.*)/;
    while ($line =~ /[-.\w\/]+/)
    {
	$_ .= $`;
	$line = $';

	if ($cache{$&})
	{
	    # Execute any previously saved substitution.

	    $value = $cache{$&};
	}
	else
	{
	    $value = $&;
	    if ($value =~ /^[^.]+\.[^.]+$/)
	    {
		# Normalize anything resembling a file name.

		$value = &filename ($value);
	    }
	}
	$_ .= $value;
    }
    $_ .= $line . "\n";

    # Check for other special modifications.

    if (/^SHELL\s*=/)
    {
	s/^/#/;
    }
    elsif (/^CC\s*=/)
    {
	$_ = "CC = tcc\n";
    }
    elsif (/^CFLAGS\s*=/)
    {
	s/-[gO]\b//g;
	s/=/= -v -N/;
    }
    elsif (/^LDFLAGS\s*=/)
    {
	s/-\w+//g;
    }
    elsif (/^	\$\(CC\).*-o\s/)
    {
	s/-o\s+/-e/;
	s/\$\(OBJECTS\)/@objects.lst/;
    }
    elsif (/^\w+\s*=\s*:\b/ || /^	:\b/)
    {
	s/:/rem/;
    }
    elsif (/^\w+\s*=\s*cp\b/ || /^	cp\b/)
    {
	s/cp(\s+-\w+)*/copy/;
    }
    elsif (/^\w+\s*=\s*rm\b/ || /^	rm\b/)
    {
	s/rm(\s+-\w+)*/erase/;
    }

    print;
}
close INPUT;
exit 0;


# Prepare substitutions for the given list of files.

sub studylist
{
    $list = $_[0];
    $list =~ s/\$\(\w+\)//g;
    $list =~ s/\\$//;
    while ($list =~ /([-.\w\/]+)/)
    {
	$list = $';
	$value = $&;
	$cache{$value} = &filename ($&);
    }
}


# Turn the argument into an MSDOS file name.

sub filename
{
    # If no period at all, let flow characters after the 8th into the
    # the extension.

    if ($_[0] =~ /^(.*\/)?([^.\/]+)$/)
    {
	($prefix, $name, $ext) = ($1, $2, "");
	$prefix =~ y/A-Z/a-z/;
	$name =~ y/A-Z/a-z/;
	if (length ($name) > 8)
	{
	    $ext = substr ($name, 8);
	    $name = substr ($name, 0, 8);
	    $ext = substr ($ext, 0, 3) if length ($ext) > 3;
	    return "$prefix$name.$ext";
	}
	return "$prefix$name";
    }

    # If only one period, truncate to 8 characters before it and to 3
    # characters after it.

    if ($_[0] =~ /^(.*\/)?([^.\/]+)\.([^.\/]+)$/)
    {
	($prefix, $name, $ext) = ($1, $2, $3);
	$prefix =~ y/A-Z/a-z/;
	$name =~ y/A-Z/a-z/;
	$ext =~ y/A-Z/a-z/;
	$name = substr ($name, 0, 8) if length ($name) > 8;
	if ($ext eq "o")
	{
	    $ext = "obj";
	}
	elsif ($ext eq "texi" || $ext eq "texinfo")
	{
	    $ext = "ti";
	}
	elsif (length ($ext) > 3)
	{
	    $ext = substr ($ext, 0, 3);
	}
	return "$prefix$name.$ext";
    }

    # In other cases, return the argument unchanged.

    return $_[0];
}
